//
// Created by LiuYou on 2021/10/28.
//

#include <iostream>
#include <unistd.h>
#include <fcntl.h>


static const char* const FILE_NAME = "/tmp/out";

static int fd;


int main(int argc, char** argv) {

//    FILE_NAME;



    fd = open( FILE_NAME, O_WRONLY | O_TRUNC | O_CREAT, 0666 );
    if (fd < 0) {
        perror( "open();" );
        return 1;
    }


    //<editor-fold desc="dup2();相当于这两部的原子操作。">
//    close( STDOUT_FILENO );
//    // 执行这个函数会
//    // 复制 参数 fd , 放到当前可用范围内最小的文件描述符,
//    // 那么就是刚刚关闭的 STDOUT_FILENO, 即 1 号。
//    dup( fd );
//    // 但是: 注意: close();和dup();这两个操作不会原子进行。
//    // 不会关了之后, 立马 dup();如果在多线程或者多进程中。
//    // 所以, dup2();设计出来了。见下一个版本。
    //</editor-fold>

    /*
     * todo 笔记: dup2();会先检查 STDOUT_FILENO 是否被使用了,
     *  如果使用了, dup2();会 close(STDOUT_FILENO);
     *  然后, 把 fd 复制一份放到 STDOUT_FILENO 去。
     */
    dup2( fd, STDOUT_FILENO );
    // 但是这样写还是不对,
    // 因为如果 fd 本身是 STDOUT_FILENO, 即 1, 怎么办?
    // dup2(); 什么都不做, 返回 这个 fd本身。

    // 但是, 错的地方在这儿！
    // 我调用 close(fd); 把 fd 关掉了。
    // todo 笔记: 注意: 所以这里需要进行判断。
    if (fd != STDOUT_FILENO) {
        close( fd );
    }



/* ************************************************* */

    puts( "你好！" );


    return 0;
}
